﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows;
using System.Windows.Forms;
using System.Threading;
using System.Drawing.Drawing2D;

namespace MMDemo
{
    enum QueueOperateType
    {
        YangHui, //杨辉三角
        CirQueue,
        CirQueueAuto,
    }
    class AnimationQueue:InterfaceDataStructs
    {
        private QueueOperateType operateType = QueueOperateType.YangHui;
        //演示动画窗口的高度和宽度
        private int Animation_Width = 0;
        private int Animation_Height = 0;

        //双缓冲画布及Graphics
        public Bitmap BufferBmp = null;
        private Graphics BufferGrap = null; 

        //动画的窗口对象
        private Form Animation_Form = null;
        private DrawHandler RefreshHandler = null;

        //杨辉三角的行数
        private int QueueOrder = 0;
        private Button button1 = null;
        private Button button2 = null;
        private int CenterX;
        private int CenterY;
        List<int> FrontLocation = new List<int>();
        List<int> RearLocation = new List<int>();

        List<String> EnQueueElement = new List<String>();
        List<String> DeQueueElement = new List<String>();
        List<String> QueueArray = new List<String>();

        public AnimationQueue(Form An_Form, DrawHandler refreshHandler, int An_Width, int An_Height)
        {
            this.Animation_Form = An_Form;
            this.RefreshHandler = refreshHandler;
            this.Animation_Width = An_Width;
            this.Animation_Height = An_Height;


            //设置画布和Graphics
            BufferBmp = new Bitmap(this.Animation_Width, this.Animation_Height);
            BufferGrap = Graphics.FromImage(BufferBmp);
        }
        public void SetButton()
        {
            button1 = new Button();
            button1.Name = "button1";
            button1.Text = "入队";
            button1.Size = new Size(70, 30);
            button1.Location = new Point(100, this.Animation_Height - 100);
            button1.Visible = true;
            button1.Enabled = false;
            this.Animation_Form.Controls.Add(button1);
            button1.BringToFront();
            button1.Click += new EventHandler(button1_Click);

            button2 = new Button();
            button2.Name = "button2";
            button2.Text = "出队";
            button2.Size = new Size(70, 30);
            button2.Location = new Point(this.Animation_Width - 170, this.Animation_Height - 100);
            button2.Visible = true;
            button2.Enabled = false;
            this.Animation_Form.Controls.Add(button2);
            button2.BringToFront();
            button2.Click += new EventHandler(button2_Click);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            button2.Enabled = false;
            SetExcuteLine(0);
            SetExcuteLine(1);
            SetExcuteLine(2);
            SetExcuteLine(3);
            if (QueueArray.Count == 0)
            {
                //DrawEnQueue();
                EnQueueExcute = true;
            }
            else
            {
                for (int i = 0; i < QueueArray.Count; i++)
                {
                    if (FrontLocation.Count == RearLocation.Count && QueueArray.Count == 4 && QueueArray[i] != null)
                    {
                        SetExcuteLine(4);
                        SetExcuteLine(5);
                        MessageBox.Show("队列满，不能进行入队操作！");
                        SetExcuteLine(6);
                        button1.Enabled = true;
                        button2.Enabled = true;
                        break;
                    }
                    else
                    {
                        //DrawEnQueue();
                        EnQueueExcute = true;
                        break;
                    }
                }
            }
            //button1.Enabled = true;
            //button2.Enabled = true;
        }
        private void button2_Click(object sender, EventArgs e)
        {
            button2.Enabled = false;
            button1.Enabled = false;
            SetExcuteLine(11);
            SetExcuteLine(12);
            SetExcuteLine(13);
            SetExcuteLine(14);
            if (QueueArray.Count == 0)
            {
                MessageBox.Show("队列空，不能进行出队操作！");
                button1.Enabled = true;
                button2.Enabled = true;
            } 
            else
            {
                for (int i = 0; i < QueueArray.Count; i++)
                {
                    if (FrontLocation.Count == RearLocation.Count && QueueArray[i] == null)
                    {
                        SetExcuteLine(15);
                        SetExcuteLine(16);
                        MessageBox.Show("队列空，不能进行出队操作！");
                        button1.Enabled = true;
                        button2.Enabled = true;
                        SetExcuteLine(17);
                        break;
                    }
                    else
                    {
                        //DrawDeQueue();
                        DeQueueExcute = true;
                        break;
                    }
                }
                return;
            }
            //for (int i = 0; i < QueueArray.Count; i++)
            //{
            //    if (FrontLocation.Count == RearLocation.Count && QueueArray[i] == null)
            //    {
            //        MessageBox.Show("队列空，不能进行出队操作！");
            //        button1.Enabled = true;
            //        button2.Enabled = true;
            //        break;
            //    }
            //    else
            //    {
            //        DrawDeQueue();
            //        break;
            //    }

            //}
            //button2.Enabled = true;
            //button1.Enabled = true;
        }
        public void SetAnimationFormSize(int Width, int Height)
        {
            this.Animation_Height = Height;
            this.Animation_Width = Width;
        }
        public void ResetData(int order)
        {
            this.QueueOrder = order;
        }

        private void SetEnQueueElement()
        {
            EnQueueElement.Add("G");
            EnQueueElement.Add("F");
            EnQueueElement.Add("E");
            EnQueueElement.Add("D");
            EnQueueElement.Add("C");
            EnQueueElement.Add("B");
            EnQueueElement.Add("A");
        }

        public void DrawYangHuiData()
        {
            BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_Width, Animation_Height);

            DrawQueueBuffer();
            DrawQueueBufferData("出队：t", 3, 55);
            DrawQueueBufferData("系数：s", 3, 145);
            DrawQueueBufferData("入队：u", 3, 235);

            int Data_x = 112;
            int Data_y = 55;

            int N = this.QueueOrder + 3;
            int[] QueueDate = new int[N];

            //初始化数组
            for (int q_size = 0; q_size < QueueDate.Length; q_size++)
            {
                QueueDate[q_size] = -2;
            }

            int n = QueueOrder;

            DrawQueueRect();

            Queue<int> q = new Queue<int>();

            int i = 1;
            int k = 0;
            int j;
            int t;
            int s = 0;
            int u = 0;
            //int EnQueueFlag = 0;
            //int DeQueueFlag = 0;

            SetExcuteLine(1);
            SetExcuteLine(2);
            SetExcuteLine(3);
            SetExcuteLine(4);
            SetExcuteLine(5);
            q.Enqueue(i);
            QueueDate[0] = i;
            DrawQueueData(i, Data_x, Data_y, 1);
            SetExcuteLine(6);
            q.Enqueue(i);
            QueueDate[1] = i;
            DrawQueueData(i, Data_x, Data_y, 2);
            
            for (i = 1; i <= n; i++)
            {
                SetExcuteLine(7);
                SetExcuteLine(8);
                q.Enqueue(k);
                {
                    if (QueueDate[QueueDate.Length - 1] == -2)
                    {
                        for (int q_s = 0; q_s < QueueDate.Length; q_s++)
                        {

                            if (QueueDate[q_s] == -2)
                            {
                                DrawQueueData(k, Data_x, Data_y, q_s + 1);
                                QueueDate[q_s] = k;
                                break;
                            }
                        }
                    }
                    else
                    {
                        for (int q_si = 0; q_si < QueueDate.Length; q_si++)
                        {
                            if (QueueDate[q_si] == -1 && q_si != 0 && QueueDate[q_si - 1] != -1)
                            {
                                BufferGrap.FillRectangle(new SolidBrush(Color.Black), 112 + q_si * 50, 52, 48, 31);
                                DrawQueueData(k, Data_x, Data_y, q_si + 1);
                                QueueDate[q_si] = k;
                                break;
                            }
                            else if (QueueDate[q_si] == -1 && q_si == 0 && QueueDate[QueueDate.Length - 1] != -1)
                            {
                                BufferGrap.FillRectangle(new SolidBrush(Color.Black), 112 + q_si * 50, 52, 48, 31);
                                DrawQueueData(k, Data_x, Data_y, q_si + 1);
                                QueueDate[q_si] = k;
                                break;
                            }
                        }
                    }



                }
                
               //////////////////////////////////////////////////////////////////////////
                
                for (j = 1; j <= i + 2; j++)
                {
                    SetExcuteLine(9);
                    SetExcuteLine(10);
                    t = q.Dequeue();

                    if (j == 1 && i == 1)
                    {
                        BufferGrap.FillRectangle(new SolidBrush(Color.Blue), 112, 52, 48, 31);
                        QueueDate[0] = -1;
                        //return;
                    }
                    else
                    {
                        for (int q_siz = 0; q_siz < QueueDate.Length; q_siz++)
                        {
                            if (QueueDate[q_siz] == -1 && q_siz + 1 < QueueDate.Length && QueueDate[q_siz + 1] != -1)
                            {
                                BufferGrap.FillRectangle(new SolidBrush(Color.Blue), 112 + (q_siz + 1) * 50, 52, 48, 31);
                                QueueDate[q_siz + 1] = -1;
                                break;
                            }
                            else if (QueueDate[q_siz] == -1 && q_siz == QueueDate.Length -1 && QueueDate[0] != -1)
                            {
                                BufferGrap.FillRectangle(new SolidBrush(Color.Blue), 112, 52, 48, 31);
                                QueueDate[0] = -1;
                                break;
                            }
                        }
                        //return;
                    }
                   

                    DrawQueueBufferRect(0, 85);
                    BufferGrap.FillRectangle(new SolidBrush(Color.Black), 1, 87, 78, 31);
                    DrawQueueBufferData(t.ToString(), 30, 90);
                    Thread.Sleep(Speed);

                    SetExcuteLine(11);
                    u = s + t;

                    DrawQueueBufferRect(0, 265);
                    BufferGrap.FillRectangle(new SolidBrush(Color.Black), 1, 267, 78, 31);
                    DrawQueueBufferData(u.ToString(), 30, 270);
                    Thread.Sleep(Speed);

                    SetExcuteLine(12);
                    q.Enqueue(u);

                    {
                        if (QueueDate[QueueDate.Length - 1] == -2)
                        {
                            for (int q_s = 0; q_s < QueueDate.Length; q_s++)
                            {

                                if (QueueDate[q_s] == -2)
                                {
                                    DrawQueueData(u, Data_x, Data_y, q_s + 1);
                                    QueueDate[q_s] = u;
                                    break;
                                }
                            }
                        } 
                        else
                        {
                            for (int q_si = 0; q_si < QueueDate.Length; q_si++)
                            {
                                if (QueueDate[q_si] == -1 && q_si != 0 && QueueDate[q_si - 1] != -1)
                                {
                                    BufferGrap.FillRectangle(new SolidBrush(Color.Black), 112 + q_si * 50, 52, 48, 31);
                                    DrawQueueData(u, Data_x, Data_y, q_si + 1);
                                    QueueDate[q_si] = u;
                                    break;
                                }
                                else if (QueueDate[q_si] == -1 && q_si == 0 && QueueDate[QueueDate.Length - 1] != -1)
                                {
                                    BufferGrap.FillRectangle(new SolidBrush(Color.Black), 112 + q_si * 50, 52, 48, 31);
                                    DrawQueueData(u, Data_x, Data_y, q_si + 1);
                                    QueueDate[q_si] = u;
                                    break;
                                }
                            }
                        }
                    }

                    SetExcuteLine(13);
                    s = t;
                    DrawQueueBufferRect(0, 175);
                    BufferGrap.FillRectangle(new SolidBrush(Color.Black), 1, 177, 78, 31);
                    DrawQueueBufferData(s.ToString(), 30, 180);

                    SetExcuteLine(14);
                    if (j != i + 2)
                    {
                        PointF pointf = new PointF(this.Animation_Width/ 2 - i * 22 + (j - 1) * 44, i * 44 + 100);
                        SolidBrush brush = new SolidBrush(Color.Red);
                        Font font = new Font("微软雅黑", 16);

                        BufferGrap.DrawString("行数：", font, brush, new PointF(this.Animation_Width - 100, i * 44 + 100));
                        BufferGrap.DrawString(i.ToString(), font, brush, new PointF(this.Animation_Width - 30, i * 44 + 100));
                        BufferGrap.DrawString(s.ToString(), font, brush, pointf);
                        Refresh();
                        Thread.Sleep(Speed);
                    }
                }
            }
            BufferGrap.Dispose();
        }
        private void DrawQueueRect()
        {
            int line_x = 100;
            BufferGrap.DrawLine(new Pen(Color.Red), new Point(line_x, 50), new Point(line_x + 50 * (this.QueueOrder + 3) + 20, 50));
            BufferGrap.DrawLine(new Pen(Color.Red), new Point(line_x, 85), new Point(line_x + 50 * (this.QueueOrder + 3) + 20, 85));
            Refresh();

        }
        private void DrawQueueBufferData(String str, int x, int y)
        {
            BufferGrap.DrawString(str, new Font("微软雅黑", 15), new SolidBrush(Color.Red), x, y);
            Refresh();
        }
        private void DrawQueueBufferRect(int x, int y)
        {
            BufferGrap.DrawRectangle(new Pen(Color.Red), x, y, 80, 35);
        }
        private void DrawQueueBuffer()
        {
            for(int i = 1; i <= 2; i++)
            {
                DrawQueueBufferRect(0, 50 + 35 * (i - 1));
            }
            for (int i = 1; i <= 2; i++)
            {
                DrawQueueBufferRect(0, 140 + 35 * (i - 1));
            }
            for (int i = 1; i <= 2; i++)
            {
                DrawQueueBufferRect(0, 230 + 35 * (i - 1));
            }
            
        }
        private void DrawQueueData(int data,int Data_x, int Data_y, int x)
        {
            PointF pf = new PointF(Data_x + (x-1)*50, Data_y);
            BufferGrap.DrawString(data.ToString(),new Font("微软雅黑",15), new SolidBrush(Color.Red),pf);
            Refresh();
            Thread.Sleep(Speed);
        }
        private void DrawQueueData_M(int data,int Data_x, int Data_y, int x)
        {
            PointF pf = new PointF(Data_x + (x - 1) * 50, Data_y);
            BufferGrap.DrawString(data.ToString(), new Font("微软雅黑", 15), new SolidBrush(Color.Red), pf);
            Refresh();
        }
        private bool Refresh()
        {
            try
            {
                if (Animation_Form.IsHandleCreated)
                    Animation_Form.Invoke(RefreshHandler);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
            return true;
        }
        private bool stop_flag = false;
        private bool EnQueueExcute = false;
        private bool DeQueueExcute = false;
        public void Animation()
        {
            if (GlobalQueue.operateType == QueueOperateType.CirQueue)
            {
                button1.Enabled = true;
                button2.Enabled = true;
            }
            while (true)
            {
                switch (operateType)
                {
                    case QueueOperateType.YangHui:
                        stop_flag = Animation_YangHui();
                        break;
                    case QueueOperateType.CirQueue:
                        //button1.Enabled = true;
                        //button2.Enabled = true;
                        if(EnQueueExcute)
                        {
                            DrawEnQueue();
                            EnQueueExcute = false;
                        }
                        if (DeQueueExcute)
                        {
                            DrawDeQueue();
                            DeQueueExcute = false;
                        }
                        stop_flag = true;
                        break;
                    case QueueOperateType.CirQueueAuto:
                        stop_flag = Animation_CirQueueAuto();
                        break;
                }
                if (!stop_flag)
                {
                    MessageBox.Show(Animation_Form, "演示结束！");
                    break;
                }
            }
            SysMainForm.AnimationForm.ChangeExcuteOverBtnsEnable();
        }
        private bool Animation_YangHui()
        {
            DrawYangHuiData();
            return false;
        }
        private bool Animation_CirQueueAuto()
        {
            DrawCirQueueAuto();
            return false;
        }
        /// <summary>
        /// 接口的重新设置数据函数
        /// </summary>
        public void ResetData()
        {
            InitData();
        }
        /// <summary>
        /// 接口的重新设置双缓冲画布函数
        /// </summary>
        public void ResetBuffer(int Width, int Height)
        {
            if (0 == Width || 0 == Height)
            {
                return;
            }
            Animation_Width = Width;
            Animation_Height = Height;
            if (null != BufferBmp)
            {
                BufferBmp.Dispose();
            }
            BufferBmp = new Bitmap(Width, Height);
            if (null != BufferGrap)
            {
                BufferGrap.Dispose();
            }
            BufferGrap = Graphics.FromImage(BufferBmp);
        }
        /// <summary>
        /// 接口的得到画布函数
        /// </summary>
        public Bitmap GetBufferBmp()
        {
            return BufferBmp;
        }
        private const int SPEED = 200;
        private int Speed = SPEED;
        public void SetSpeed(float scale)
        {
            Speed = (int)(SPEED * scale);
        }

        public void InitData()
        {
            operateType = GlobalQueue.operateType;
            switch (operateType)
            {
                case QueueOperateType.YangHui:
                    BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, this.Animation_Width, this.Animation_Height);
                    Refresh();
                    ResetData(GlobalQueue.YangHuiOrderData); 
                    break;
                case QueueOperateType.CirQueue:
                    BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, this.Animation_Width, this.Animation_Height);
                    this.CenterX = this.Animation_Width / 2;
                    this.CenterY = this.Animation_Height / 2 - 50;
                    QueueArray.Clear();
                    DeQueueElement.Clear();
                    EnQueueElement.Clear();
                    FrontLocation.Clear();
                    RearLocation.Clear();
                    SetEnQueueElement();
                    SetButton();
                    DrawAll();
                    DrawPointer();
                    Refresh();
                    break;
                case QueueOperateType.CirQueueAuto:
                    BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, this.Animation_Width, this.Animation_Height);
                    this.CenterX = this.Animation_Width / 2;
                    this.CenterY = this.Animation_Height / 2 - 50;
                    QueueArray.Clear();
                    DeQueueElement.Clear();
                    FrontLocation.Clear();
                    EnQueueElement.Clear();
                    RearLocation.Clear();
                    SetEnQueueElement();
                    GetDeEnpElement();
                    DrawAll();
                    DrawPointer();
                    DrawEnDeElement(-1);
                    Refresh();
                    EnQueueExcute = false;
                    DeQueueExcute = false;
                    break;
            }
        }
        private void SetExcuteLine(int line)
        {
            if (line != GlobalLink.cur_line)
            {
                GlobalLink.cur_line = line;
                Thread.Sleep((int)(1000 * PublicDataClass.scale));
                SysMainForm.AnimationForm.SetSelectLine(line);
            }
        }
        private int DoNum = 0;
        private void DrawCirQueueAuto()
        {
            for (int i = 0; i < EnDeElement.Length; ++i)
            {
                if (EnDeElement[i] == 1)
                {
                    SetExcuteLine(0); 
                    SetExcuteLine(1);
                    SetExcuteLine(2);
                    SetExcuteLine(3);
                    Thread.Sleep(SPEED);
                    DrawEnQueue();
                    DoNum++;
                }
                else
                {
                    SetExcuteLine(11);
                    SetExcuteLine(12);
                    SetExcuteLine(13);
                    SetExcuteLine(14);
                    Thread.Sleep(SPEED);
                    DrawDeQueue();
                    DoNum++;
                }
            }
        }
        int[] EnDeElement = new int[14];
        
        private void GetDeEnpElement()
        {
            int StackFlag = 0;
            int StackNum = 0;
            Random ran = new Random();
            for (int i = 0; i < 14; i++)
            {
                if (ran.Next(0, StackFlag + 1) == 0 && StackFlag < 4 && StackNum < 7)
                {
                    StackNum++;
                    StackFlag += 1;
                    EnDeElement[i] = 1;
                }
                else
                {
                    StackFlag -= 1;
                    EnDeElement[i] = 0;
                }
            }
        }
        private void DrawInitialize()
        {
            DrawEnElement();
            DrawDeElement(); ;

            BufferGrap.FillEllipse(new SolidBrush(Color.Blue), CenterX - 75, CenterY - 75, 150, 150);
            BufferGrap.FillEllipse(new SolidBrush(Color.Black), CenterX - 40, CenterY - 40, 80, 80);
            BufferGrap.DrawLine(new Pen(Color.GreenYellow, 5), new Point(CenterX - 40, CenterY), new Point(CenterX - 75, CenterY));
            BufferGrap.DrawLine(new Pen(Color.GreenYellow, 5), new Point(CenterX + 40, CenterY), new Point(CenterX + 75, CenterY));
            BufferGrap.DrawLine(new Pen(Color.GreenYellow, 5), new Point(CenterX, CenterY - 40), new Point(CenterX, CenterY - 75));
            BufferGrap.DrawLine(new Pen(Color.GreenYellow, 5), new Point(CenterX, CenterY + 40), new Point(CenterX, CenterY + 75));
            BufferGrap.DrawString("0", new Font("微软雅黑", 15), new SolidBrush(Color.Red), new PointF(CenterX + 13, CenterY - 28));
            BufferGrap.DrawString("1", new Font("微软雅黑", 15), new SolidBrush(Color.Red), new PointF(CenterX + 13, CenterY + 3));
            BufferGrap.DrawString("2", new Font("微软雅黑", 15), new SolidBrush(Color.Red), new PointF(CenterX - 23, CenterY + 3));
            BufferGrap.DrawString("3", new Font("微软雅黑", 15), new SolidBrush(Color.Red), new PointF(CenterX - 23, CenterY - 28));

            Pen pFront = new Pen(Color.Orange, 5);
            Pen pRear = new Pen(Color.PaleGreen, 5);
            pFront.EndCap = LineCap.ArrowAnchor;
            pRear.EndCap = LineCap.ArrowAnchor;
            BufferGrap.DrawLine(pRear, new Point(CenterX + 170, CenterY - 10), new Point(CenterX + 150, CenterY - 10));
            BufferGrap.DrawString("队尾", new Font("微软雅黑", 15), new SolidBrush(Color.PaleGreen), new PointF(CenterX + 170, CenterY - 30));
            BufferGrap.DrawLine(pFront, new Point(CenterX + 170, CenterY + 10), new Point(CenterX + 150, CenterY + 10));
            BufferGrap.DrawString("队头", new Font("微软雅黑", 15), new SolidBrush(Color.Orange), new PointF(CenterX + 170, CenterY));
            DrawQueueArray();
        }
        private void DrawEnDeElement(int n)
        {
            if (GlobalQueue.operateType == QueueOperateType.CirQueueAuto)
            {
                BufferGrap.DrawString("操作序列:", new Font("微软雅黑", 15), new SolidBrush(Color.Red),
                    new PointF(CenterX - 280, CenterY + 200));
                for (int i = 0; i < EnDeElement.Length; ++i)
                {
                    BufferGrap.DrawString(EnDeElement[i].ToString(), new Font("微软雅黑", 15), new SolidBrush(Color.Red),
                        new PointF(CenterX - 180 + i * 30, CenterY + 200));
                }
                if (n != -1)
                {
                    BufferGrap.DrawString(EnDeElement[n].ToString(), new Font("微软雅黑", 15), new SolidBrush(Color.Yellow),
                        new PointF(CenterX - 180 + n * 30, CenterY + 200));
                }
                BufferGrap.DrawString("0表示出队，1表示入队", new Font("微软雅黑", 15), new SolidBrush(Color.Yellow), new PointF(CenterX - 100, CenterY + 250));
            }
        }
        private void DrawPointer()
        {
            Pen pFront = new Pen(Color.Orange, 5);
            Pen pRear = new Pen(Color.PaleGreen, 5);
            pFront.EndCap = LineCap.ArrowAnchor;
            pRear.EndCap = LineCap.ArrowAnchor;

            int f, r;
            f = FrontLocation.Count;
            r = RearLocation.Count; ;

            switch (f)
            {
                case 0: BufferGrap.DrawLine(pFront, new Point(CenterX + 52 + 10 + 20, CenterY - 52 - 20),
                                    new Point(CenterX + 52 + 10, CenterY - 52));
                    break;
                case 1: BufferGrap.DrawLine(pFront, new Point(CenterX + 52 + 20, CenterY + 52 + 10 + 20),
                                    new Point(CenterX + 52, CenterY + 52 + 10));
                    break;
                case 2: BufferGrap.DrawLine(pFront, new Point(CenterX - 52 - 10 - 20, CenterY + 52 + 20),
                                    new Point(CenterX - 52 - 10, CenterY + 52));
                    break;
                case 3: BufferGrap.DrawLine(pFront, new Point(CenterX - 52 - 20, CenterY - 52 - 10 - 20),
                                    new Point(CenterX - 52, CenterY - 52 - 10));
                    break;
            }
            switch (r)
            {
                case 0: BufferGrap.DrawLine(pRear, new Point(CenterX + 52 + 20, CenterY - 52 - 10 - 20),
                                   new Point(CenterX + 52, CenterY - 52 - 10));
                    break;
                case 1: BufferGrap.DrawLine(pRear, new Point(CenterX + 52 + 10 + 20, CenterY + 52 + 20),
                                    new Point(CenterX + 52 + 10, CenterY + 52));
                    break;
                case 2: BufferGrap.DrawLine(pRear, new Point(CenterX - 52 - 20, CenterY + 52 + 10 + 20),
                                     new Point(CenterX - 52, CenterY + 52 + 10));
                    break;
                case 3: BufferGrap.DrawLine(pRear, new Point(CenterX - 52 - 10 - 20, CenterY - 52 - 20),
                                      new Point(CenterX - 52 - 10, CenterY - 52));
                    break;
            }

        }
        private void DrawEnElement()
        {
            BufferGrap.DrawLine(new Pen(Color.AliceBlue, 4),
                        new Point(30, CenterY + 75), new Point(240, CenterY + 75));
            BufferGrap.DrawString("入队列序列", new Font("微软雅黑", 15),
                        new SolidBrush(Color.Blue), new Point(60, CenterY + 80));
            for (int i = 0; i < EnQueueElement.Count; ++i)
            {
                BufferGrap.DrawString(EnQueueElement[i], new Font("微软雅黑", 15),
                            new SolidBrush(Color.GreenYellow), new PointF(30 + i * 30, CenterY + 50));
            }
        }
        private void DrawDeElement()
        {
            BufferGrap.DrawLine(new Pen(Color.AliceBlue, 4), new Point(Animation_Width - 30, CenterY + 75),
                        new Point(Animation_Width - 240, CenterY + 75));
            BufferGrap.DrawString("出队列序列", new Font("微软雅黑", 15), new SolidBrush(Color.Blue),
                        new Point(Animation_Width - 210, CenterY + 80));
            for (int i = 0; i < DeQueueElement.Count; ++i)
            {
                BufferGrap.DrawString(DeQueueElement[i], new Font("微软雅黑", 15), new SolidBrush(Color.GreenYellow),
                            new PointF(Animation_Width - 60 - i * 30, CenterY + 50));
            }
        }
        private void DrawQueueArray()
        {
            for (int i = 0; i < QueueArray.Count; ++i)
            {
                if (QueueArray[i] != null)
                {
                    switch (i)
                    {
                        case 0:
                            BufferGrap.DrawString(QueueArray[i], new Font("微软雅黑", 15), new SolidBrush(Color.Yellow),
                                        new PointF(CenterX + 30, CenterY - 30 - 15));
                            break;
                        case 1:
                            BufferGrap.DrawString(QueueArray[i], new Font("微软雅黑", 15), new SolidBrush(Color.Yellow),
                                        new PointF(CenterX + 30, CenterY + 30));
                            break;
                        case 2:
                            BufferGrap.DrawString(QueueArray[i], new Font("微软雅黑", 15), new SolidBrush(Color.Yellow),
                                        new PointF(CenterX - 30 - 15, CenterY + 30));
                            break;
                        case 3:
                            BufferGrap.DrawString(QueueArray[i], new Font("微软雅黑", 15), new SolidBrush(Color.Yellow),
                                        new PointF(CenterX - 30 - 15, CenterY - 30 - 15));
                            break;
                    }
                }
            }
        }
        private void DrawEnQueue()
        {
            SetExcuteLine(7);
            String temp;
            temp = EnQueueElement[EnQueueElement.Count - 1];
            EnQueueElement.RemoveAt(EnQueueElement.Count - 1);
            DrawMove_EnQueue(temp, EnQueueElement.Count, FrontLocation.Count);
            if (QueueArray.Count < 4)
            {
                QueueArray.Add(temp);
            }
            else
            {
                QueueArray[FrontLocation.Count] = temp;
            }
            FrontLocation.Add(1);
            if (FrontLocation.Count == 4)
            {
                FrontLocation.Clear();
            }
            SetExcuteLine(8);
            Thread.Sleep(Speed);
            DrawAll();
            DrawEnDeElement(DoNum);
            DrawPointer();
            Refresh();
            SetExcuteLine(9);
            SetExcuteLine(10);
            if(GlobalQueue.operateType == QueueOperateType.CirQueue)
            {
                button1.Enabled = true;
                button2.Enabled = true;
            }
        }
        private void DrawMove_EnQueue(String temp, int source, int destination)
        {
            int MoveStep = 5;
            int x = 210 - (7 - source - 1) * 30;
            int y = CenterY + 50;
            int MaxY = 0;
            int MaxX = 0;
            switch (destination)
            {
                case 0:
                    MaxX = CenterX + 30;
                    MaxY = CenterY - 30 - 15;
                    break;
                case 1:
                    MaxX = CenterX + 30;
                    MaxY = CenterY + 30;
                    break;
                case 2:
                    MaxX = CenterX - 30 - 15;
                    MaxY = CenterY + 30;
                    break;
                case 3:
                    MaxX = CenterX - 30 - 15;
                    MaxY = CenterY - 30 - 15;
                    break;
            }
            while (y > MaxY + 5)
            {
                y -= MoveStep;
                Thread.Sleep(Speed);
                DrawAll();
                DrawEnDeElement(DoNum);
                DrawPointer();
                BufferGrap.DrawString(temp, new Font("微软雅黑", 15), new SolidBrush(Color.GreenYellow),
                                        new PointF(x, y));
                    Refresh();
            }
            while (x < MaxX - 5)
            {
                x += MoveStep;
                Thread.Sleep(Speed);
                DrawAll();
                DrawEnDeElement(DoNum);
                DrawPointer();
                BufferGrap.DrawString(temp, new Font("微软雅黑", 15), new SolidBrush(Color.GreenYellow),
                                        new PointF(x, y));
                    Refresh();
            }
        }
        private void DrawDeQueue()
        {
            if (RearLocation.Count == 4)
            {
                RearLocation.Clear();
            }
            SetExcuteLine(18);
            String temp = null; ;
            temp = QueueArray[RearLocation.Count];
            QueueArray[RearLocation.Count] = null;
            DrawMove_DeQueue(temp, RearLocation.Count, DeQueueElement.Count);
            RearLocation.Add(1);
            if (RearLocation.Count == 4)
            {
                RearLocation.Clear();
            }
            DeQueueElement.Add(temp);
            SetExcuteLine(19);
            Thread.Sleep(Speed);
            DrawAll();
            DrawEnDeElement(DoNum);
            DrawPointer();
            Refresh();
            SetExcuteLine(20);
            SetExcuteLine(21);
            if (GlobalQueue.operateType == QueueOperateType.CirQueue)
            {
                button1.Enabled = true;
                button2.Enabled = true;
            }
        }
        private void DrawMove_DeQueue(String temp, int source, int destination)
        {
            int MoveStep = 5;
            int x = 0;
            int y = 0;
            int MaxY = CenterY + 50;
            int MaxX = Animation_Width - 60 - (destination) * 30;
            switch (source)
            {
                case 0:
                    x = CenterX + 30;
                    y = CenterY - 30 - 15;
                    break;
                case 1:
                    x = CenterX + 30;
                    y = CenterY + 30;
                    break;
                case 2:
                    x = CenterX - 30 - 15;
                    y = CenterY + 30;
                    break;
                case 3:
                    x = CenterX - 30 - 15;
                    y = CenterY - 30 - 15;
                    break;
            }
            while (x < MaxX - 5)
            {
                x += MoveStep;
                Thread.Sleep(Speed);
                DrawAll();
                DrawEnDeElement(DoNum);
                DrawPointer();
                BufferGrap.DrawString(temp, new Font("微软雅黑", 15), new SolidBrush(Color.GreenYellow),
                                        new PointF(x, y));
                    Refresh();
            }
            while (y < MaxY - 5)
            {
                y += MoveStep;
                Thread.Sleep(Speed);
                DrawAll();
                DrawEnDeElement(DoNum);
                DrawPointer();
                BufferGrap.DrawString(temp, new Font("微软雅黑", 15), new SolidBrush(Color.GreenYellow),
                                        new PointF(x, y));
                if (GlobalQueue.operateType == QueueOperateType.CirQueue)
                {
                    Refresh();
                }
                else
                {
                    Refresh();
                }
            }
        }
        private void DrawAll()
        {
            BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, this.Animation_Width, this.Animation_Height);
            DrawInitialize();
        }
    }
}
